﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

namespace PPSkin.NetWorkHelper
{
    /// <summary>
    /// TCP客户端
    /// </summary>
    public class PPTcpClient
    {
        public PPTcpClient()
        {
        }

        #region 枚举

        /// <summary>
        /// 连接状态
        /// </summary>
        public enum ConncetType
        {
            Conncet,
            ReConncet,
            DisConncet
        }

        #endregion 枚举

        #region 变量

        public IClient Client = null;
        private Thread _startThread = null;
        private int _reConnectCount = 0;//重连计数
        private ConncetType _conncetType = ConncetType.Conncet;
        private bool _isReconnect = true;//是否开启断开重连
        private int _reConnectTime = 3000;//重连间隔时间
        private bool _isStart = false;// 是否启动

        #endregion 变量

        #region 属性

        /// <summary>
        /// 服务端IP
        /// </summary>
        private string _serverip = "127.0.0.1";

        /// <summary>
        /// 服务端IP
        /// </summary>
        public string ServerIp
        {
            set { _serverip = value; }
            get { return _serverip; }
        }

        /// <summary>
        /// 服务端监听端口
        /// </summary>
        private int _serverport = 5000;

        /// <summary>
        /// 服务端监听端口
        /// </summary>
        public int ServerPort
        {
            set { _serverport = value; }
            get { return _serverport; }
        }

        /// <summary>
        /// 网络端点
        /// </summary>
        private IPEndPoint _ipEndPoint = null;

        /// <summary>
        /// 网络端点
        /// </summary>
        internal IPEndPoint IpEndPoint
        {
            get
            {
                try
                {
                    IPAddress ipAddress = null;
                    ipAddress = string.IsNullOrEmpty(ServerIp)
                        ? IPAddress.Any
                        : IPAddress.Parse(CommonMethod.HostnameToIp(ServerIp));

                    _ipEndPoint = new IPEndPoint(ipAddress, ServerPort);
                }
                catch
                {
                }
                return _ipEndPoint;
            }
        }

        /// <summary>
        /// 是否重连
        /// </summary>
        public bool IsReconnection
        {
            set { _isReconnect = value; }
            get { return _isReconnect; }
        }

        /// <summary>
        /// 设置断开重连时间间隔单位（毫秒）（默认3000毫秒）
        /// </summary>
        public int ReConnectionTime
        {
            get { return _reConnectTime; }
            set { _reConnectTime = value; }
        }

        /// <summary>
        /// 是否启动
        /// </summary>
        public bool IsStart
        {
            get { return _isStart; }
            set { _isStart = value; }
        }

        #endregion 属性

        #region 启动停止方法

        public void StartConnect()
        {
            if (IsStart)
                return;
            if (_startThread == null || !_startThread.IsAlive)
            {
                _startThread = new Thread(StartThread);
                _startThread.IsBackground = true;
                _startThread.Start();
            }
        }

        /// <summary>
        /// 启动客户端基础的一个线程
        /// </summary>
        private void StartThread()
        {
            if (_conncetType == ConncetType.ReConncet && IsReconnection) //如果是重连的延迟N秒
            {
                Thread.Sleep(ReConnectionTime);
                TcpClientStateInfo(string.Format("正在第{0}次重连", _reConnectCount), SocketState.Reconnection);
            }
            else
            {
                TcpClientStateInfo("正在连接服务器... ...", SocketState.Connecting);
            }
            try
            {
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.SendTimeout = 1000;
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);
                socket.BeginConnect(IpEndPoint, new AsyncCallback(AcceptCallback), socket);
                IsStart = true;
            }
            catch (Exception ex)
            {
                TcpClientErrorMsg(string.Format("连接服务器失败，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                Reconnect();
            }
        }

        /// <summary>
        /// 当连接服务器之后的回调函数
        /// </summary>
        /// <param name="ar">TcpClient</param>
        private void AcceptCallback(IAsyncResult ar)
        {
            try
            {
                Socket socket = (Socket)ar.AsyncState;
                socket.EndConnect(ar);

                Client = new IClient(socket);
                Client.WorkSocket.BeginReceive(Client.BufferInfo.ReceivedBuffer, 0, Client.BufferInfo.ReceivedBuffer.Length, 0, new AsyncCallback(ReadCallback), Client);
                _conncetType = ConncetType.Conncet;
                TcpClientStateInfo(string.Format("已连接服务器"), SocketState.Connected);
                _reConnectCount = 0;
            }
            catch (SocketException ex)
            {
                string msg = ex.Message;
                if (ex.NativeErrorCode.Equals(10060))
                {
                    //无法连接目标主机
                    msg = string.Format("{0} 无法连接: error code {1}!", "", ex.NativeErrorCode);
                }
                else if (ex.NativeErrorCode.Equals(10061))
                {
                    msg = string.Format("{0} 主动拒绝正在重连: error code {1}!", "", ex.NativeErrorCode);
                }
                else if (ex.NativeErrorCode.Equals(10053))
                {
                    //读写时主机断开
                    msg = string.Format("{0} 主动断开连接: error code {1}! ", "", ex.NativeErrorCode);
                }
                else
                {
                    //其他错误
                    msg = string.Format("Disconnected: error code {0}!", ex.NativeErrorCode);
                }

                TcpClientErrorMsg(string.Format("连接服务器失败，错误原因：{0}", msg));
                Reconnect();
            }
        }

        #endregion 启动停止方法

        #region 发送数据

        public void SendData(byte[] data)
        {
            try
            {
                if (Client != null)
                {
                    //异步发送数据
                    //cModel.ClientSocket.Send(data);
                    Client.WorkSocket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), Client);
                }
            }
            catch (SocketException ex)
            {
                TcpClientErrorMsg(string.Format("向服务端户端发送数据时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }

        /// <summary>
        /// 发送完数据之后的回调函数
        /// </summary>
        /// <param name="ar">Clicent</param>
        private void SendCallback(IAsyncResult ar)
        {
            IClient iClient = (IClient)ar.AsyncState;
            if (iClient == null)
                return;
            Socket handler = iClient.WorkSocket;
            try
            {
                int bytesSent = handler.EndSend(ar);
            }
            catch (Exception ex)
            {
                TcpClientErrorMsg(string.Format("发送数据后回调时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }

        #endregion 发送数据

        #region 接收数据

        /// <summary>
        /// 当接收到数据之后的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void ReadCallback(IAsyncResult ar)
        {
            if (Client == null)
                return;
            Socket handler = Client.WorkSocket;
            try
            {
                int bytesRead = handler.EndReceive(ar);
                if (bytesRead > 0)
                {
                    byte[] bytes = new byte[bytesRead];
                    Array.Copy(Client.BufferInfo.ReceivedBuffer, 0, bytes, 0, bytesRead);
                    TcpClientRecevice(bytes);
                    handler.BeginReceive(Client.BufferInfo.ReceivedBuffer, 0, Client.BufferInfo.ReceivedBuffer.Length, 0, new AsyncCallback(ReadCallback), Client);
                }
                else
                {
                    Reconnect();
                }
            }
            catch (Exception ex)
            {
                TcpClientErrorMsg(string.Format("接收数据失败，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                Reconnect();
            }
        }

        #endregion 接收数据

        #region 重连

        /// <summary>
        /// 重连模块
        /// </summary>
        private void Reconnect()
        {
            if (_conncetType == ConncetType.Conncet)
            {
                TcpClientStateInfo(string.Format("已断开服务器{0}", IsReconnection ? "，准备重连" : ""), SocketState.Disconnect);
            }
            if (!IsReconnection)
            {
                return;
            }
            _reConnectCount++;//每重连一次重连的次数加1
            if (Client != null)
            {
                Client.WorkSocket.Close();
                Client = null;
            }
            if (_conncetType == ConncetType.Conncet)
            {
                _conncetType = ConncetType.ReConncet;

                //CommonMethod.EventInvoket(() => { ReconnectionStart(); });
            }
            _isStart = false;
            StartConnect();
        }

        #endregion 重连

        #region 断开

        /// <summary>
        /// 关闭相连的scoket以及关联的StateObject,释放所有的资源
        /// </summary>
        public void StopConnect()
        {
            if (Client != null)
            {
                ShutdownClient(Client);
                Client.WorkSocket.Close();
            }
            IsStart = false;
            _conncetType = ConncetType.Conncet;
            _reConnectCount = 0;//前面三个初始化
        }

        private void ShutdownClient(IClient iClient)
        {
            try
            {
                iClient.WorkSocket.Shutdown(SocketShutdown.Both);
            }
            catch
            {
            }
        }

        #endregion 断开

        #region 事件

        #region OnRecevice接收数据事件

        /// <summary>
        /// 接收数据事件
        /// </summary>
        public event EventHandler<TcpClientReceviceEventArgs> OnRecevice;

        protected virtual void TcpClientRecevice(byte[] data)
        {
            OnRecevice?.Invoke(this, new TcpClientReceviceEventArgs(data));
        }

        #endregion OnRecevice接收数据事件

        #region OnErrorMsg返回错误消息事件

        /// <summary>
        /// 返回错误消息事件
        /// </summary>
        public event EventHandler<TcpClientErrorEventArgs> OnErrorMsg;

        protected virtual void TcpClientErrorMsg(string msg)
        {
                OnErrorMsg?.Invoke(this, new TcpClientErrorEventArgs(msg));
        }

        #endregion OnErrorMsg返回错误消息事件

        #region OnStateInfo连接状态改变时返回连接状态事件

        /// <summary>
        /// 连接状态改变时返回连接状态事件
        /// </summary>
        public event EventHandler<TcpClientStateEventArgs> OnStateInfo;

        protected virtual void TcpClientStateInfo(string msg, SocketState state)
        {
                OnStateInfo?.Invoke(this, new TcpClientStateEventArgs(msg, state));
        }

        #endregion OnStateInfo连接状态改变时返回连接状态事件

        #endregion 事件

        /// <summary>
        /// TCP连接设备，连接成功后发送消息，发送完成后断开连接,无返回值
        /// </summary>
        /// <param name="ip">服务端的ip地址</param>
        /// <param name="port">服务端端口</param>
        /// <param name="sendMsg">要发送的消息</param>
        /// <returns>发送成功返回true，失败返回false</returns>
        public static bool sendTcpMsg(string ip, int port, byte[] sendMsg)
        {
            IPAddress IP = IPAddress.Parse(ip);
            IPEndPoint ipe = new IPEndPoint(IP, port);
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                IAsyncResult result = client.BeginConnect(ipe, null, null);
                if (!result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2)))
                {
                    //client.EndConnect(result);
                    client.Close();
                    client.Dispose();
                    return false;
                }
                //client.Connect(ipe);
                Thread.Sleep(50);
                bool Connected = !client.Poll(10, SelectMode.SelectRead);
                if (Connected)
                {
                    byte[] bmsg = sendMsg;
                    client.Send(bmsg, bmsg.Length, 0);//发送测试信息
                }
                else
                {
                    client.Close();
                    client.Dispose();
                    return false;
                }
                client.Close();
                client.Dispose();
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// TCP连接设备，连接成功后发送消息，发送完成后断开连接,无返回值,有超时时间
        /// </summary>
        /// <param name="ip">服务端的ip地址</param>
        /// <param name="port">服务端端口</param>
        /// <param name="sendMsg">要发送的结构体</param>
        /// <param name="timeout">超时时间</param>
        /// <returns>发送成功返回true，失败返回false</returns>
        public static bool sendTcpMsgWithTimeOut(string ip, int port, byte[] sendMsg, int timeout)
        {
            bool ret = false;
            new System.Threading.Tasks.TaskFactory().StartNew(() =>
            {
                ret = sendTcpMsg(ip, port, sendMsg);
            }).Wait(timeout);
            return ret;
        }

        /// <summary>
        /// 发送TCP消息并等待返回字节数组
        /// </summary>
        /// <param name="ip">服务端ip</param>
        /// <param name="port">服务端端口</param>
        /// <param name="sendMsg">发送的结构体</param>
        /// <param name="rtnmsgLen">返回数据长度，默认2048</param>
        /// <returns>成功返回字节数组，失败返回null</returns>
        public static byte[] sendTcpMsgWaitReturn(string ip, int port, byte[] sendMsg, int rtnmsgLen = 2048)
        {
            IPAddress IP = IPAddress.Parse(ip);
            IPEndPoint ipe = new IPEndPoint(IP, port);
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                if (ipe != null)
                {
                    IAsyncResult result = client.BeginConnect(ipe, null, null);
                    if (!result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2)))
                    {
                        //client.EndConnect(result);
                        client.Close();
                        client.Dispose();
                        return null;
                    }
                    //client.Connect(ipe);
                }
                else
                {
                    return null;
                }

                Thread.Sleep(50);
                bool Connected = !client.Poll(10, SelectMode.SelectRead);
                if (Connected)
                {
                    byte[] bmsg = sendMsg;//发送的消息转字节数组
                    client.Send(bmsg, bmsg.Length, 0);//发送测试信息
                    byte[] Rbmsg = new byte[rtnmsgLen];//接收的字节数组
                    int readsize = client.Receive(Rbmsg, Rbmsg.Length, 0);
                    if (Rbmsg != null && readsize > 0)
                    {
                        byte[] msg = new byte[readsize];
                        msg = Rbmsg.Skip(0).Take(readsize).ToArray();
                        return msg;
                    }
                }
                else
                {
                    client.Close();
                    client.Dispose();
                    return null;
                }
                client.Close();
                client.Dispose();
            }
            catch
            {
                return null;
            }
            return null;
        }

        /// <summary>
        /// 发送TCP消息并等待返回结构体，超时返回null
        /// </summary>
        /// <param name="ip">服务端ip</param>
        /// <param name="port">服务端端口</param>
        /// <param name="sendMsg">发送的结构体</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="rtnmsgLen">返回数据长度，默认2048</param>
        /// <returns>成功返回结构体，失败或超时返回null</returns>
        public static byte[] sendTcpMsgWaitReturnWithTimeout(string ip, int port, byte[] sendMsg, int timeout, int rtnmsgLen = 2048)
        {
            byte[] ret = null;
            new System.Threading.Tasks.TaskFactory().StartNew(() =>
            {
                ret = sendTcpMsgWaitReturn(ip, port, sendMsg, rtnmsgLen);
            }).Wait(timeout);
            return ret;
        }
    }

    /// <summary>
    /// TCP服务端
    /// </summary>
    public class PPTcpServer
    {
        public PPTcpServer()
        {
        }

        #region 变量

        // 监听Socket
        private Socket _serverSocket = null;

        // 心跳检测线程
        private Thread _tHeartCheck = null;

        //监听IP，为空时监听本机所有IP
        private string _serverIp = "";

        //监听端口
        private int _serverPort = 5000;

        //网络端点
        private IPEndPoint _ipEndPoint = null;

        //是否开启心跳检测
        private bool _isHeartCheck = true;

        //心跳检测间隔
        private int _checkTime = 3000;

        //是否已启动监听
        private bool _isStartListening = false;

        //客户端列表
        private List<IClient> _clientList;

        #endregion 变量

        #region 属性

        /// <summary>
        /// 设置服务端IP，无IP地址时默认监听本机所有IP
        /// </summary>
        public string ServerIp
        {
            get { return _serverIp; }
            set { _serverIp = value; }
        }

        /// <summary>
        /// 本机监听端口
        /// </summary>
        public int ServerPort
        {
            get { return _serverPort; }
            set { _serverPort = value; }
        }

        /// <summary>
        /// 网络端点,IP+PORT
        /// </summary>
        internal IPEndPoint IpEndPoint
        {
            get
            {
                try
                {
                    IPAddress ipAddress = null;
                    if (ServerIp == "")
                        ipAddress = IPAddress.Any;
                    else
                        ipAddress = IPAddress.Parse(CommonMethod.HostnameToIp(ServerIp));
                    _ipEndPoint = new IPEndPoint(ipAddress, ServerPort);
                }
                catch
                {
                }
                return _ipEndPoint;
            }
        }

        /// <summary>
        /// 是否开启心跳检测
        /// </summary>
        public bool IsHeartCheck
        {
            get { return _isHeartCheck; }
            set { _isHeartCheck = value; }
        }

        /// <summary>
        /// 心跳检测时间,单位：毫秒
        /// </summary>
        public int CheckTime
        {
            get { return _checkTime; }
            set { _checkTime = value; }
        }

        /// <summary>
        /// 是否已启动监听
        /// </summary>
        public bool IsStartListening
        {
            get { return _isStartListening; }
            set { _isStartListening = value; }
        }

        /// <summary>
        /// 客户端列表
        /// </summary>
        public List<IClient> ClientSocketList
        {
            get
            {
                if (_clientList == null)
                {
                    _clientList = new List<IClient>();
                }
                return _clientList;
            }
        }

        #endregion 属性

        #region 接口实现方法

        /// <summary>
        /// 开启监听
        /// </summary>
        public void Start()
        {
            if (IsStartListening)
                return;
            StartListen();
        }

        /// <summary>
        /// 启动服务器,没出现异常,则启动成功
        /// </summary>
        private void StartListen()
        {
            IsStartListening = true;
            try
            {
                _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _serverSocket.Bind(IpEndPoint);
                _serverSocket.Listen(10000);
                TcpServerStateInfo(null, string.Format("服务端Ip:{0},端口:{1}已启动监听", ServerIp, ServerPort),
                    SocketState.StartListening);
                TcpServerGetLog(null, LogType.Server,
                    string.Format("服务端Ip:{0},端口:{1}已启动监听", string.IsNullOrEmpty(ServerIp) ? "本机所有IP" : ServerIp,
                        ServerPort));
                _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
                if (_tHeartCheck == null)
                {
                    _tHeartCheck = new Thread(new ThreadStart(HeartCheckThread));
                    _tHeartCheck.IsBackground = true;
                    _tHeartCheck.Start();
                }
                IsStartListening = true;
            }
            catch (Exception ex)
            {
                IsStartListening = false;
                TcpServerStateInfo(null, string.Format("服务端Ip:{0},端口:{1}启动监听失败", ServerIp, ServerPort),
                    SocketState.StartListeningError);
                TcpServerGetLog(null, LogType.Server, ex.Message);
            }
        }

        /// <summary>
        /// 停止监听，释放所有资源
        /// </summary>
        public void Stop()
        {
            try
            {
                IsStartListening = false;
                if (_serverSocket != null)
                {
                    _serverSocket.Close();
                }
                _serverSocket = null;

                if (_tHeartCheck != null)
                {
                    _tHeartCheck.Interrupt();
                    _tHeartCheck.Join();
                }
                _tHeartCheck = null;
                CloseClient();
                ClientSocketList.Clear();
                TcpServerReturnClientCount(ClientSocketList.Count);
                TcpServerStateInfo(null, string.Format("服务端已停止监听"), SocketState.StopListening);
                TcpServerGetLog(null, LogType.Server, "服务端已停止监听");
            }
            catch (Exception ex)
            {
                TcpServerErrorMsg(string.Format("停止监听时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }

        #endregion 接口实现方法

        #region 心跳检测方法模块

        /// <summary>
        /// 心跳检测
        /// </summary>
        private void HeartCheckThread()
        {
            try
            {
                while (IsStartListening)
                {
                    try
                    {
                        Thread.Sleep(CheckTime);
                        if (!IsHeartCheck)
                        {
                            //如果没有开启心跳检测或者没有启动监听则跳过检测
                            continue;
                        }
                        int i = 0;
                        while (i < ClientSocketList.Count)
                        {
                            try
                            {
                                Thread.Sleep(1);
                                if (!IsStartListening)
                                {
                                    break;
                                }
                                byte[] sendHeartbeatData = new byte[0];
                                if (ClientSocketList[i].ClientInfo.HeartCheckType == HeartCheckType.EncodingString)
                                {
                                    if (!string.IsNullOrEmpty(ClientSocketList[i].ClientInfo.Heartbeat))
                                    {
                                        sendHeartbeatData =
                                            Encoding.Default.GetBytes(ClientSocketList[i].ClientInfo.Heartbeat);
                                    }
                                }
                                else if (ClientSocketList[i].ClientInfo.HeartCheckType == HeartCheckType.HexString)
                                {
                                    sendHeartbeatData =
                                        CommonMethod.StringToHexByteArray(
                                            ClientSocketList[i].ClientInfo.Heartbeat);
                                }
                                else if (ClientSocketList[i].ClientInfo.HeartCheckType == HeartCheckType.Byte)
                                {
                                    sendHeartbeatData = ClientSocketList[i].ClientInfo.HeartbeatByte;
                                }
                                if (sendHeartbeatData.Length > 0)
                                {
                                    if (ClientSocketList[i].ClientStyle == ClientStyle.WebSocket)
                                    {
                                        SendToWebClient(ClientSocketList[i],
                                            Encoding.Default.GetString(sendHeartbeatData));
                                    }
                                    else
                                    {
                                        SendData(ClientSocketList[i], sendHeartbeatData);
                                    }
                                }
                                i++;
                            }
                            catch (Exception ex)
                            {
                                TcpServerErrorMsg(string.Format("心跳检测时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                                try
                                {
                                    if (ClientSocketList[i].WorkSocket != null)
                                    {
                                        TcpServerOfflineClient(ClientSocketList[i]);
                                        ClientSocketList.Remove(ClientSocketList[i]);
                                        TcpServerReturnClientCount(ClientSocketList.Count);
                                    }
                                }
                                catch (Exception e)
                                {
                                    TcpServerErrorMsg(string.Format("处理心跳检测异常时发生错误，错误原因：{0},行号{1}", ex.Message, e.StackTrace));
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        TcpServerErrorMsg(string.Format("心跳检测异常处理时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// 手动检测
        /// </summary>
        public void HandCheck()
        {
            int i = 0;
            while (i < ClientSocketList.Count)
            {
                Thread.Sleep(1);

                if (ClientSocketList[i] == null)
                {
                    TcpServerOfflineClient(ClientSocketList[i]);
                    ClientSocketList.RemoveAt(i);
                    TcpServerReturnClientCount(ClientSocketList.Count);
                    continue;
                }
                string sendLoginMsg = string.IsNullOrEmpty(ClientSocketList[i].ClientInfo.Heartbeat) ? "客户端\r\n" : ClientSocketList[i].ClientInfo.Heartbeat;
                try
                {
                    SendData(ClientSocketList[i], Encoding.Default.GetBytes(sendLoginMsg));
                    i++;
                }
                catch (Exception ex)
                {
                    TcpServerErrorMsg(string.Format("手动检测时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                    try
                    {
                        if (ClientSocketList[i].WorkSocket != null)
                        {
                            TcpServerOfflineClient(ClientSocketList[i]);
                            ClientSocketList.Remove(ClientSocketList[i]);
                            TcpServerReturnClientCount(ClientSocketList.Count);
                        }
                        continue;
                    }
                    catch (Exception e)
                    {
                        TcpServerErrorMsg(string.Format("手动检测异常处理时发生错误，错误原因：{0}", e.Message));
                    }
                }
            }
        }

        #endregion 心跳检测方法模块

        #region Socket相关方法

        /// <summary>
        /// 异步监听当有客户端连接后的回调函数
        /// </summary>
        /// <param name="iar"></param>
        private void AcceptCallback(IAsyncResult iar)
        {
            IClient iClient = null;
            try
            {
                if (_serverSocket != null)
                    _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
            }
            catch (Exception ex)
            {
                TcpServerErrorMsg(string.Format("监听客户端连接状态时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                Stop();
            }
            try
            {
                if (_serverSocket != null)
                {
                    Socket workSocket = _serverSocket.EndAccept(iar);
                    iClient = new IClient(workSocket);
                    ClientSocketList.Add(iClient);
                    TcpServerStateInfo(iClient, string.Format("<{0}：{1}>---上线", iClient.Ip, iClient.Port),
                        SocketState.ClientOnline);

                    TcpServerGetLog(iClient, LogType.Client, "客户端上线"); //记录
                    TcpServerOnlineClient(iClient);
                    TcpServerReturnClientCount(ClientSocketList.Count);
                    iClient.WorkSocket.BeginReceive(iClient.BufferInfo.ReceivedBuffer, 0,
                        iClient.BufferInfo.ReceivedBuffer.Length, 0,
                        new AsyncCallback(ClientReadCallback), iClient);
                }
            }
            catch (Exception ex)
            {
                ShutdownClient(iClient);
                TcpServerOfflineClient(iClient);
                ClientSocketList.Remove(iClient);
                TcpServerReturnClientCount(ClientSocketList.Count);
                TcpServerErrorMsg(string.Format("监听客户端时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }

        /// <summary>
        /// 异步接收数据
        /// </summary>
        /// <param name="ar"></param>
        private void ClientReadCallback(IAsyncResult ar)
        {
            IClient iClient = (IClient)ar.AsyncState;
            try
            {
                int bytesRead = iClient.WorkSocket.EndReceive(ar);
                if (bytesRead > 0)
                {
                    //byte[] haveDate = ReceiveDateOne.DateOneManage(iClient, bytesRead);//接收完成之后对数组进行重置
                    byte[] bytes = new byte[bytesRead];
                    Array.Copy(iClient.BufferInfo.ReceivedBuffer, 0, bytes, 0, bytesRead);
                    string clientRecevieStr = "";

                    #region WebSocket验证

                    //验证websocket握手协议
                    if (iClient != null && iClient.ClientStyle != ClientStyle.WebSocket)
                    {
                        clientRecevieStr = ASCIIEncoding.Default.GetString(iClient.BufferInfo.ReceivedBuffer, 0, bytesRead);
                        //如果客户端不存在则退出检测
                        WebSocketHandShake(iClient, clientRecevieStr, bytes);
                    }
                    if (iClient.ClientStyle == ClientStyle.WebSocket)
                    {
                        string webstr = AnalyticData(bytes, bytes.Length);
                        clientRecevieStr = webstr;
                        bytes = Encoding.Default.GetBytes(clientRecevieStr);
                    }

                    #endregion WebSocket验证

                    TcpServerRecevice(iClient, bytes);
                    TcpServerGetLog(iClient, LogType.ReceviedData, CommonMethod.HexByteArrayToString(bytes));
                    iClient.WorkSocket.BeginReceive(iClient.BufferInfo.ReceivedBuffer, 0,
                        iClient.BufferInfo.ReceivedBuffer.Length, 0,
                        new AsyncCallback(ClientReadCallback), iClient);
                }
                else if (bytesRead == 0)
                {
                    //接收数据长度为0时，标示客户单下线
                    if (iClient != null)
                    {
                        ShutdownClient(iClient);
                        TcpServerStateInfo(iClient, string.Format("<{0}：{1}>---下线", iClient.Ip, iClient.Port),
                            SocketState.ClientOnOff);
                        RemoveClient(iClient, "客户端下线");
                        TcpServerOfflineClient(iClient);
                        ClientSocketList.Remove(iClient);
                        TcpServerReturnClientCount(ClientSocketList.Count);
                    }
                }
            }
            catch (Exception ex)
            {
                TcpServerErrorMsg(string.Format("接收客户端数据时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                int i = ex.Message.IndexOf("远程主机强迫关闭了一个现有的连接");
                if (iClient != null && i != -1)
                {
                    RemoveClient(iClient, ex.Message);
                }
                iClient = null;
            }
        }

        #endregion Socket相关方法

        #region websocket模块

        public void WebSocketHandShake(IClient iClient, string msg, byte[] data)
        {
            #region 网络WebSocket协议握手

            string webkey = GetSecKey(data, data.Length);
            if (!string.IsNullOrEmpty(webkey) && iClient.ClientStyle != ClientStyle.WebSocket)
            {
                byte[] bufferwoshou = PackHandShakeData(webkey);
                if (bufferwoshou.Length > 0)
                {
                    iClient.ClientStyle = ClientStyle.WebSocket;
                    iClient.WorkSocket.Send(bufferwoshou);
                }
            }
            else
            {
            }

            #endregion 网络WebSocket协议握手
        }

        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="recBytes"></param>
        /// <param name="recByteLength"></param>
        /// <returns></returns>
        public string AnalyticData(byte[] recBytes, int recByteLength)
        {
            //byte[] bytes = new byte[recByteLength];
            //Array.Copy(recBytes, 0, bytes, 0, recByteLength);
            //return Encoding.Default.GetString(bytes);

            if (recByteLength < 2) { return string.Empty; }

            bool fin = (recBytes[0] & 0x80) == 0x80; // 1bit，1表示最后一帧
            if (!fin)
            {
                return string.Empty;// 超过一帧暂不处理
            }

            bool mask_flag = (recBytes[1] & 0x80) == 0x80; // 是否包含掩码
            if (!mask_flag)
            {
                return string.Empty;// 不包含掩码的暂不处理
            }

            int payload_len = recBytes[1] & 0x7F; // 数据长度

            byte[] masks = new byte[4];
            byte[] payload_data;

            if (payload_len == 126)
            {
                Array.Copy(recBytes, 4, masks, 0, 4);
                payload_len = (UInt16)(recBytes[2] << 8 | recBytes[3]);
                payload_data = new byte[payload_len];
                Array.Copy(recBytes, 8, payload_data, 0, payload_len);
            }
            else if (payload_len == 127)
            {
                Array.Copy(recBytes, 10, masks, 0, 4);
                byte[] uInt64Bytes = new byte[8];
                for (int i = 0; i < 8; i++)
                {
                    uInt64Bytes[i] = recBytes[9 - i];
                }
                UInt64 len = BitConverter.ToUInt64(uInt64Bytes, 0);

                payload_data = new byte[len];
                for (UInt64 i = 0; i < len; i++)
                {
                    payload_data[i] = recBytes[i + 14];
                }
            }
            else
            {
                Array.Copy(recBytes, 2, masks, 0, 4);
                payload_data = new byte[payload_len];
                Array.Copy(recBytes, 6, payload_data, 0, payload_len);
            }

            for (var i = 0; i < payload_len; i++)
            {
                payload_data[i] = (byte)(payload_data[i] ^ masks[i % 4]);
            }

            return Encoding.UTF8.GetString(payload_data);
        }

        /// <summary>
        /// 向客户端发送信息
        /// </summary>
        /// <param name="iClient">客户端</param>
        /// <param name="sendData">发送的数据包</param>
        public void SendToWebClient(IClient iClient, string sendData)
        {
            if (iClient == null)
            {
                return;
            }
            if (!iClient.WorkSocket.Connected)
            {
                return;
            }
            try
            {
                DataFrame dr = new DataFrame(sendData);
                iClient.WorkSocket.Send(dr.GetBytes());
            }
            catch
            {
                //logger.Log(ex.Message);
            }
        }

        /// <summary>
        /// 打包服务器数据
        /// </summary>
        /// <param name="message">数据</param>
        /// <returns>数据包</returns>
        private byte[] PackData(string message)
        {
            byte[] contentBytes = null;
            byte[] temp = Encoding.UTF8.GetBytes(message);

            if (temp.Length < 126)
            {
                contentBytes = new byte[temp.Length + 2];
                contentBytes[0] = 0x81;
                contentBytes[1] = (byte)temp.Length;
                Array.Copy(temp, 0, contentBytes, 2, temp.Length);
            }
            else if (temp.Length < 0xFFFF)
            {
                contentBytes = new byte[temp.Length + 4];
                contentBytes[0] = 0x81;
                contentBytes[1] = 126;
                contentBytes[2] = (byte)(temp.Length & 0xFF);
                contentBytes[3] = (byte)(temp.Length >> 8 & 0xFF);
                Array.Copy(temp, 0, contentBytes, 4, temp.Length);
            }
            else
            {
                // 暂不处理超长内容
            }

            return contentBytes;
        }

        /// <summary>
        /// 打包握手信息
        /// </summary>
        /// <param name="secKeyAccept">Sec-WebSocket-Accept</param>
        /// <returns>数据包</returns>
        public byte[] PackHandShakeData(string secKeyAccept)
        {
            var responseBuilder = new StringBuilder();
            responseBuilder.Append("HTTP/1.1 101 Switching Protocols" + Environment.NewLine);
            responseBuilder.Append("Upgrade: websocket" + Environment.NewLine);
            responseBuilder.Append("Connection: Upgrade" + Environment.NewLine);
            responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine + Environment.NewLine);
            //如果把上一行换成下面两行，才是thewebsocketprotocol-17协议，但居然握手不成功，目前仍没弄明白！
            //responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine);
            //responseBuilder.Append("Sec-WebSocket-Protocol: chat" + Environment.NewLine);

            return Encoding.UTF8.GetBytes(responseBuilder.ToString());
        }

        /// <summary>
        /// 生成Sec-WebSocket-Accept
        /// </summary>
        /// <param name="handShakeText">客户端握手信息</param>
        /// <returns>Sec-WebSocket-Accept</returns>
        public string GetSecKeyAccetp(byte[] handShakeBytes, int bytesLength)
        {
            string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);
            string key = string.Empty;
            Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n");
            Match m = r.Match(handShakeText);
            if (m.Groups.Count != 0)
            {
                key = Regex.Replace(m.Value, @"Sec\-WebSocket\-Key:(.*?)\r\n", "$1").Trim();
            }
            if (key == "")
            {
                return handShakeText;
            }
            byte[] encryptionString = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); //这字符串是固定的.不能改
            string str = Convert.ToBase64String(encryptionString);
            return str;
        }

        public string GetSecKey(byte[] handShakeBytes, int bytesLength)
        {
            string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);
            string key = string.Empty;
            Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n");
            Match m = r.Match(handShakeText);
            if (m.Groups.Count != 0)
            {
                key = Regex.Replace(m.Value, @"Sec\-WebSocket\-Key:(.*?)\r\n", "$1").Trim();
            }
            if (key == "")
            {
                return string.Empty;
            }
            byte[] encryptionString = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); //这字符串是固定的.不能改
            string str = Convert.ToBase64String(encryptionString);
            return str;
        }

        #endregion websocket模块

        #region 组件方法

        internal void CloseClient()
        {
            foreach (IClient iClient in ClientSocketList)
            {
                RemoveClient(iClient, "服务器主动关闭客户端");
            }
        }

        /// <summary>
        /// 关闭相连的scoket以及关联的TcpState,释放所有的资源
        /// </summary>
        /// <param name="iClient">TcpState</param>
        /// <param name="str">原因</param>
        internal void RemoveClient(IClient iClient, string str)
        {
            if (iClient == null)
                return;
            try
            {
                ShutdownClient(iClient);
                iClient.WorkSocket.Close();
                TcpServerOfflineClient(iClient);
                TcpServerGetLog(iClient, LogType.Client, str); //记录
            }
            catch (Exception ex)
            {
                TcpServerErrorMsg(string.Format("释放客户端资源时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }

        /// <summary>
        /// 强制断开与某个客户端的连接
        /// </summary>
        /// <param name="iClient"></param>
        public void ShutdownClient(IClient iClient)
        {
            try
            {
                iClient.WorkSocket.Shutdown(SocketShutdown.Both);
            }
            catch
            {
            }
        }

        #endregion 组件方法

        #region 发送数据

        /// <summary>
        /// 向指定客户端发送字符串数据
        /// </summary>
        /// <param name="iClient"></param>
        /// <param name="msg"></param>
        /// <param name="isHexString"></param>
        public void SendData(IClient iClient, string msg, bool isHexString = false)
        {
            byte[] data;
            if (isHexString)
            {
                data = CommonMethod.StringToHexByteArray(msg);
            }
            else
            {
                data = Encoding.Default.GetBytes(msg);
            }
            SendData(iClient, data);
        }

        /// <summary>
        /// 向指定IP和端口客户端发送字符串数据
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="msg"></param>
        /// <param name="isHexString"></param>
        public void SendData(string ip, int port, string msg, bool isHexString = false)
        {
            IClient iClient = FindIClient(ip, port);
            if (iClient == null)
            {
                return;
            }
            byte[] data;
            if (isHexString)
            {
                data = CommonMethod.StringToHexByteArray(msg);
            }
            else
            {
                data = Encoding.Default.GetBytes(msg);
            }
            SendData(iClient, data);
        }

        /// <summary>
        /// 向指定IP和端口客户端发送数据
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="data"></param>
        public void SendData(string ip, int port, byte[] data)
        {
            IClient iClient = FindIClient(ip, port);
            if (iClient == null)
            {
                return;
            }
            SendData(iClient, data);
        }

        /// <summary>
        /// 向指定客户端发送数据(基础)
        /// </summary>
        /// <param name="iClient">客户端</param>
        /// <param name="data">字节数组数据</param>
        public void SendData(IClient iClient, byte[] data)
        {
            try
            {
                if (iClient != null)
                {
                    if (!iClient.WorkSocket.Connected)
                    {
                        DisposeClient(iClient);
                        return;
                    }
                    //异步发送数据
                    //cModel.ClientSocket.Send(data);
                    iClient.WorkSocket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), iClient);
                    iClient.BufferInfo.SendBuffer = data;
                    TcpServerGetLog(iClient, LogType.SendData, CommonMethod.HexByteArrayToString(data));
                }
            }
            catch
            {
                DisposeClient(iClient);
            }
        }

        public void DisposeClient(IClient iClient)
        {
            try
            {
                if (iClient == null)
                {
                    ClientSocketList.Remove(iClient);
                    TcpServerReturnClientCount(ClientSocketList.Count);
                    return;
                }
                ShutdownClient(iClient);
                TcpServerOfflineClient(iClient);
                TcpServerErrorMsg(string.Format("强制关闭远程客户端时发生错误"));
                TcpServerGetLog(iClient, LogType.SendData, "强制关闭远程客户端时发生错误");
                ClientSocketList.Remove(iClient);
                TcpServerReturnClientCount(ClientSocketList.Count);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 发送完数据之后的回调函数
        /// </summary>
        /// <param name="ar">Clicent</param>
        private void SendCallback(IAsyncResult ar)
        {
            IClient iClient = (IClient)ar.AsyncState;
            try
            {
                if (iClient == null)
                    return;
                Socket handler = iClient.WorkSocket;

                int bytesSent = handler.EndSend(ar);
                TcpServerSendDateSuccess(iClient, bytesSent);
                TcpServerGetLog(iClient, LogType.SendDataResult, string.Format("发送成功，字节数：{0}", bytesSent));
            }
            catch (Exception ex)
            {
                TcpServerErrorMsg(string.Format("发送数据后回调时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                TcpServerGetLog(iClient, LogType.SendDataResult, string.Format("发送失败，失败原因：{0},行号{1}", ex.Message, ex.StackTrace));
            }
        }

        #endregion 发送数据

        #region 查找客户端方法

        /// <summary>
        /// 根据IP,端口查找Socket客户端
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public IClient FindIClient(string ip, int port)
        {
            try
            {
                foreach (IClient iClient in ClientSocketList)
                {
                    if (iClient.Ip.Equals(ip)
                        && iClient.Port.Equals(port))
                    {
                        return iClient;
                    }
                }
                return null;
            }
            catch
            {
                return null;
            }
        }

        #endregion 查找客户端方法

        #region 注册事件

        #region OnRecevice接收数据事件

        /// <summary>
        /// 接收数据事件
        /// </summary>
        public event EventHandler<TcpServerReceviceaEventArgs> OnRecevice;

        protected virtual void TcpServerRecevice(IClient iClient, byte[] data)
        {
            if (OnRecevice != null)
            {
                try
                {
                    OnRecevice(this, new TcpServerReceviceaEventArgs(iClient, data));
                }
                catch (Exception ex)
                {
                    TcpServerErrorMsg(string.Format("接收客户端数据时发生错误，错误原因：{0},行号{1}", ex.Message, ex.StackTrace));
                }
            }
        }

        #endregion OnRecevice接收数据事件

        #region OnErrorMsg返回错误消息事件

        /// <summary>
        /// 接收数据事件
        /// </summary>
        public event EventHandler<TcpServerErrorEventArgs> OnErrorMsg;

        protected virtual void TcpServerErrorMsg(string msg)
        {
            if (OnErrorMsg != null)
            {
                OnErrorMsg(this, new TcpServerErrorEventArgs(msg));
            }
        }

        #endregion OnErrorMsg返回错误消息事件

        #region OnReturnClientCount用户上线下线时更新客户端在线数量事件

        /// <summary>
        /// 用户上线下线时更新客户端在线数量事件
        /// </summary>
        public event EventHandler<TcpServerReturnClientCountEventArgs> OnReturnClientCount;

        /// <summary>
        /// 用户上线下线时更新客户端在线数量事件
        /// </summary>
        /// <param name="count"></param>
        protected virtual void TcpServerReturnClientCount(int count)
        {
            if (OnReturnClientCount != null)
            {
                OnReturnClientCount(this, new TcpServerReturnClientCountEventArgs(count));
            }
        }

        #endregion OnReturnClientCount用户上线下线时更新客户端在线数量事件

        #region OnStateInfo监听状态改变时返回监听状态事件

        /// <summary>
        /// 监听状态改变时返回监听状态事件
        /// </summary>
        public event EventHandler<TcpServerStateEventArgs> OnStateInfo;

        protected virtual void TcpServerStateInfo(IClient iClient, string msg, SocketState state)
        {
            if (OnStateInfo != null)
            {
                OnStateInfo(this, new TcpServerStateEventArgs(iClient, msg, state));
            }
        }

        #endregion OnStateInfo监听状态改变时返回监听状态事件

        #region OnAddClient新客户端上线时返回客户端事件

        /// <summary>
        /// 新客户端上线时返回客户端事件
        /// </summary>
        public event EventHandler<TcpServerClientEventArgs> OnOnlineClient;

        protected virtual void TcpServerOnlineClient(IClient iclient)
        {
            if (OnOnlineClient != null)
            {
                OnOnlineClient(this, new TcpServerClientEventArgs(iclient));
            }
        }

        #endregion OnAddClient新客户端上线时返回客户端事件

        #region OnOfflineClient客户端下线时返回客户端事件

        /// <summary>
        /// 客户端下线时返回客户端事件
        /// </summary>
        public event EventHandler<TcpServerClientEventArgs> OnOfflineClient;

        protected virtual void TcpServerOfflineClient(IClient iclient)
        {
            if (OnOfflineClient != null)
            {
                OnOfflineClient(this, new TcpServerClientEventArgs(iclient));
            }
        }

        #endregion OnOfflineClient客户端下线时返回客户端事件

        #region OnGetLog服务端读写操作时返回日志消息

        /// <summary>
        /// 服务端读写操作时返回日志消息
        /// </summary>
        public event EventHandler<TcpServerLogEventArgs> OnGetLog;

        protected virtual void TcpServerGetLog(IClient temp, LogType logType, string logMsg)
        {
            if (OnGetLog != null)
            {
                OnGetLog(this, new TcpServerLogEventArgs(temp, logType, logMsg));
            }
        }

        #endregion OnGetLog服务端读写操作时返回日志消息

        #region OnSendDateSuccess发送消息成功时返回成功消息事件

        /// <summary>
        /// 发送消息成功时返回成功消息事件
        /// </summary>
        public event EventHandler<TcpServerSendReturnEventArgs> OnSendDateSuccess;

        protected virtual void TcpServerSendDateSuccess(IClient temp, int byteLen)
        {
            if (OnSendDateSuccess != null)
            {
                OnSendDateSuccess(this, new TcpServerSendReturnEventArgs(temp, byteLen));
            }
        }

        #endregion OnSendDateSuccess发送消息成功时返回成功消息事件

        #endregion 注册事件
    }

    //UDP客户端
    public class PPUdpClient
    {
        public PPUdpClient()
        {
        }

        internal UdpClient UDPclient;
        private IPEndPoint _udpEndpoint = new IPEndPoint(IPAddress.Any, 1234);
        private bool _isListening = false;

        /// <summary>
        /// udp监听IP端口
        /// </summary>
        public IPEndPoint UdpEndpoint
        {
            get { return _udpEndpoint; }
            set { _udpEndpoint = value; }
        }

        /// <summary>
        /// 是否正在监听
        /// </summary>
        public bool IsListening
        {
            get { return _isListening; }
        }

        public void Start()
        {
            if (!_isListening)
            {
                UDPclient = new UdpClient(_udpEndpoint.Port);

                IPAddress[] localIPs = Dns.GetHostEntry(Dns.GetHostName()).AddressList;//获取本机所有IP地址
                for (int i = 0; i < localIPs.Length; i++)
                {
                    if (localIPs[i].AddressFamily == AddressFamily.InterNetwork)//若地址是IPV4(筛选)
                    {
                        try
                        {
                            UDPclient.JoinMulticastGroup(_udpEndpoint.Address, localIPs[i]);//添加地址到广播组
                        }
                        catch
                        {
                        }
                    }
                }

                UDPclient.BeginReceive(new AsyncCallback(OnReceiveUdpMsg), UDPclient);
                _isListening = true;
            }
        }

        public void Stop()
        {
            lock (udpLock)
            {
                if (UDPclient != null)
                {
                    UDPclient.Close();
                    UDPclient = null;
                    _isListening = false;
                }
            }
        }

        public void Send(byte[] buffer)
        {
            //IPAddress[] localIPs = Dns.GetHostEntry(Dns.GetHostName()).AddressList;//获取本机所有IP地址
            //for (int i = 0; i < localIPs.Length; i++)
            //{
            //    if (localIPs[i].AddressFamily == AddressFamily.InterNetwork)//若地址是IPV4(筛选)
            //    {
            try
            {
                UDPclient.BeginSend(buffer, buffer.Length, UdpEndpoint, new AsyncCallback(SendCallback), UDPclient);
            }
            catch
            {
            }
            //}
            //}
        }

        private object udpLock = new object();

        private void OnReceiveUdpMsg(IAsyncResult iar)
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, _udpEndpoint.Port);
            lock (udpLock)
            {
                try
                {
                    if (UDPclient != null)
                    {
                        byte[] Rmsg = UDPclient.EndReceive(iar, ref endPoint);

                        OnReceiveData(new UdpReceiveDataEventArgs(Rmsg, endPoint));
                    }
                }
                catch
                {
                }
                finally
                {
                    lock (udpLock)
                    {
                        if (UDPclient != null)
                            UDPclient.BeginReceive(new AsyncCallback(OnReceiveUdpMsg), UDPclient);
                    }
                }
            }
        }

        private void SendCallback(IAsyncResult result)
        {
            try
            {
                UDPclient.EndSend(result);
            }
            catch (SocketException ex)
            {
                throw ex;
            }
        }

        public event EventHandler<UdpReceiveDataEventArgs> OnReceive;

        /// <summary>
        /// UDP服务端接收数据事件
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnReceiveData(UdpReceiveDataEventArgs e)
        {
            if (OnReceive != null)
            {
                OnReceive(this, e);
            }
        }
    }

    /// <summary>
    /// 公共方法
    /// </summary>
    public class CommonMethod
    {
        /// <summary>
        /// 域名转换为IP地址
        /// </summary>
        /// <param name="hostname">域名或IP地址</param>
        /// <returns>IP地址</returns>
        internal static string HostnameToIp(string hostname)
        {
            try
            {
                IPAddress ip;
                if (IPAddress.TryParse(hostname, out ip))
                    return ip.ToString();
                else
                    return System.Net.Dns.GetHostEntry(hostname).AddressList[0].ToString();
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// 十六进制字符串转为字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] StringToHexByteArray(string s)
        {
            try
            {
                s = s.Replace(" ", "");
                if ((s.Length % 2) != 0)
                    s += " ";
                byte[] returnBytes = new byte[s.Length / 2];
                for (int i = 0; i < returnBytes.Length; i++)
                    returnBytes[i] = Convert.ToByte(s.Substring(i * 2, 2), 16);
                return returnBytes;
            }
            catch
            {
                return new byte[0];
            }
        }

        /// <summary>
        /// 字节数组转为十六进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <param name="intervalChar"></param>
        /// <returns></returns>
        public static string HexByteArrayToString(byte[] data, char intervalChar = ' ')
        {
            try
            {
                StringBuilder sb = new StringBuilder(data.Length * 3);
                foreach (byte b in data)
                {
                    sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, intervalChar));
                }
                return sb.ToString().ToUpper();//将得到的字符全部以字母大写形式输出
            }
            catch
            {
                return "";
            }
        }
    }

    public class IClient
    {
        public IClient()
        {
            ClientStyle = ClientStyle.PcSocket;
            Username = "";
            Password = "";
            BufferInfo = new BufferInfo();
            ClientInfo = new ClientInfo();
        }

        public IClient(Socket socket)
        {
            WorkSocket = socket;
            if (socket != null)
            {
                Ip = ((IPEndPoint)WorkSocket.RemoteEndPoint).Address.ToString();
                Port = ((IPEndPoint)WorkSocket.RemoteEndPoint).Port;
            }
            ClientStyle = ClientStyle.PcSocket;
            Username = "";
            Password = "";
            BufferInfo = new BufferInfo();
            ClientInfo = new ClientInfo();
        }

        /// <summary>
        /// Socket
        /// </summary>
        public Socket WorkSocket { get; set; }

        /// <summary>
        /// 客户端端口IP
        /// </summary>
        public string Ip { get; set; }

        /// <summary>
        /// 客户端端口
        /// </summary>
        public int Port { get; set; }

        /// <summary>
        /// Socket类型（网页版或者PC版）
        /// </summary>
        public ClientStyle ClientStyle { get; set; }

        /// <summary>
        /// 客户端登录账号
        /// </summary>
        public string Username { get; set; }

        /// <summary>
        /// 客户端登录密码
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// 客户端信息类
        /// </summary>
        public ClientInfo ClientInfo { get; set; }

        /// <summary>
        /// 数据缓存区信息
        /// </summary>
        public BufferInfo BufferInfo { get; set; }

        /// <summary>
        /// 自定义数据
        /// </summary>
        public object CustomData { get; set; }

        /// <summary>
        /// 是否已登录
        /// </summary>
        public bool IsLogin { get; set; }
    }

    public class ClientInfo
    {
        /// <summary>
        /// 心跳检测模式
        /// </summary>
        public HeartCheckType HeartCheckType = HeartCheckType.EncodingString;

        /// <summary>
        /// 心跳包数组数据【如果长度为0为空则不发送心跳包】
        /// </summary>
        public byte[] HeartbeatByte = new byte[0];

        /// <summary>
        /// 心跳包字符串【如果为空则不发送心跳包】
        /// </summary>
        public string Heartbeat = "";

        /// <summary>
        /// 客户端ID
        /// </summary>
        public int ClientId { get; set; }

        /// <summary>
        /// 客户端编号
        /// </summary>
        public string ClientNo { get; set; }

        /// <summary>
        /// 是否授权
        /// </summary>
        public bool IsAuthorization { get; set; }

        /// <summary>
        /// 指令操作类型
        /// </summary>
        public string OrderType = "";
    }

    public class BufferInfo
    {
        //备份缓冲区
        private byte[] _bufferBackup = null;

        /// <summary>
        /// 备份缓冲区;动态增大或缩小缓冲区的时候用到；
        /// </summary>
        internal byte[] BufferBackup
        {
            get { return _bufferBackup; }
            set { _bufferBackup = value; }
        }

        /// <summary>
        /// 接收缓冲区
        /// </summary>
        public byte[] ReceivedBuffer = new byte[1024];

        /// <summary>
        /// 发送缓冲区
        /// </summary>
        public byte[] SendBuffer = new byte[1024];

        /// <summary>
        /// 接收的字符串信息
        /// </summary>
        public string RecevidMsg = "";
    }

    public class DataFrameHeader
    {
        private bool _fin;
        private bool _rsv1;
        private bool _rsv2;
        private bool _rsv3;
        private sbyte _opcode;
        private bool _maskcode;
        private sbyte _payloadlength;

        public bool FIN
        { get { return _fin; } }

        public bool RSV1
        { get { return _rsv1; } }

        public bool RSV2
        { get { return _rsv2; } }

        public bool RSV3
        { get { return _rsv3; } }

        public sbyte OpCode
        { get { return _opcode; } }

        public bool HasMask
        { get { return _maskcode; } }

        public sbyte Length
        { get { return _payloadlength; } }

        public DataFrameHeader(byte[] buffer)
        {
            if (buffer.Length < 2)
                throw new Exception("无效的数据头.");

            //第一个字节
            _fin = (buffer[0] & 0x80) == 0x80;
            _rsv1 = (buffer[0] & 0x40) == 0x40;
            _rsv2 = (buffer[0] & 0x20) == 0x20;
            _rsv3 = (buffer[0] & 0x10) == 0x10;
            _opcode = (sbyte)(buffer[0] & 0x0f);

            //第二个字节
            _maskcode = (buffer[1] & 0x80) == 0x80;
            _payloadlength = (sbyte)(buffer[1] & 0x7f);
        }

        //发送封装数据
        public DataFrameHeader(bool fin, bool rsv1, bool rsv2, bool rsv3, sbyte opcode, bool hasmask, int length)
        {
            _fin = fin;
            _rsv1 = rsv1;
            _rsv2 = rsv2;
            _rsv3 = rsv3;
            _opcode = opcode;
            //第二个字节
            _maskcode = hasmask;
            _payloadlength = (sbyte)length;
        }

        //返回帧头字节
        public byte[] GetBytes()
        {
            byte[] buffer = { 0, 0 };

            if (_fin) buffer[0] ^= 0x80;
            if (_rsv1) buffer[0] ^= 0x40;
            if (_rsv2) buffer[0] ^= 0x20;
            if (_rsv3) buffer[0] ^= 0x10;

            buffer[0] ^= (byte)_opcode;

            if (_maskcode) buffer[1] ^= 0x80;

            buffer[1] ^= (byte)_payloadlength;

            return buffer;
        }
    }

    public class DataFrame
    {
        private DataFrameHeader _header;
        private byte[] _extend = new byte[0];
        private byte[] _mask = new byte[0];
        private byte[] _content = new byte[0];

        public DataFrame(byte[] buffer)
        {
            //帧头
            _header = new DataFrameHeader(buffer);

            //扩展长度
            if (_header.Length == 126)
            {
                _extend = new byte[2];
                Buffer.BlockCopy(buffer, 2, _extend, 0, 2);
            }
            else if (_header.Length == 127)
            {
                _extend = new byte[8];
                Buffer.BlockCopy(buffer, 2, _extend, 0, 8);
            }

            //是否有掩码
            if (_header.HasMask)
            {
                _mask = new byte[4];
                Buffer.BlockCopy(buffer, _extend.Length + 2, _mask, 0, 4);
            }

            //消息体
            if (_extend.Length == 0)
            {
                _content = new byte[_header.Length];
                Buffer.BlockCopy(buffer, _extend.Length + _mask.Length + 2, _content, 0, _content.Length);
            }
            else if (_extend.Length == 2)
            {
                int contentLength = (int)_extend[0] * 256 + (int)_extend[1];
                _content = new byte[contentLength];
                Buffer.BlockCopy(buffer, _extend.Length + _mask.Length + 2, _content, 0, contentLength > 1024 * 100 ? 1024 * 100 : contentLength);
            }
            else
            {
                long len = 0;
                int n = 1;
                for (int i = 7; i >= 0; i--)
                {
                    len += (int)_extend[i] * n;
                    n *= 256;
                }
                _content = new byte[len];
                Buffer.BlockCopy(buffer, _extend.Length + _mask.Length + 2, _content, 0, _content.Length);
            }

            if (_header.HasMask) _content = Mask(_content, _mask);
        }

        public DataFrame(string content)
        {
            _content = Encoding.UTF8.GetBytes(content);
            int length = _content.Length;

            if (length < 126)
            {
                _extend = new byte[0];
                _header = new DataFrameHeader(true, false, false, false, 1, false, length);
            }
            else if (length < 65536)
            {
                _extend = new byte[2];
                _header = new DataFrameHeader(true, false, false, false, 1, false, 126);
                _extend[0] = (byte)(length / 256);
                _extend[1] = (byte)(length % 256);
            }
            else
            {
                _extend = new byte[8];
                _header = new DataFrameHeader(true, false, false, false, 1, false, 127);

                int left = length;
                int unit = 256;

                for (int i = 7; i > 1; i--)
                {
                    _extend[i] = (byte)(left % unit);
                    left = left / unit;

                    if (left == 0)
                        break;
                }
            }
        }

        public byte[] GetBytes()
        {
            byte[] buffer = new byte[2 + _extend.Length + _mask.Length + _content.Length];
            Buffer.BlockCopy(_header.GetBytes(), 0, buffer, 0, 2);
            Buffer.BlockCopy(_extend, 0, buffer, 2, _extend.Length);
            Buffer.BlockCopy(_mask, 0, buffer, 2 + _extend.Length, _mask.Length);
            Buffer.BlockCopy(_content, 0, buffer, 2 + _extend.Length + _mask.Length, _content.Length);
            return buffer;
        }

        public string Text
        {
            get
            {
                if (_header.OpCode != 1)
                    return string.Empty;

                return Encoding.UTF8.GetString(_content);
            }
        }

        private byte[] Mask(byte[] data, byte[] mask)
        {
            for (var i = 0; i < data.Length; i++)
            {
                data[i] = (byte)(data[i] ^ mask[i % 4]);
            }

            return data;
        }
    }

    /// <summary>
    /// 心跳检测模式
    /// </summary>
    public enum HeartCheckType
    {
        /// <summary>
        /// 字符串模式
        /// </summary>
        EncodingString,

        /// <summary>
        /// 十六进制字符串
        /// </summary>
        HexString,

        /// <summary>
        /// byte数组模式
        /// </summary>
        Byte
    }

    /// <summary>
    /// 客户端类型
    /// </summary>
    public enum ClientStyle
    {
        WebSocket,
        PcSocket
    }

    public class TcpClientStateEventArgs : EventArgs
    {
        public TcpClientStateEventArgs(string stateInfo, SocketState state)
        {
            StateInfo = stateInfo;
            State = state;
        }

        /// <summary>
        /// 状态爱信息
        /// </summary>
        public string StateInfo { get; set; }

        /// <summary>
        /// 状态
        /// </summary>
        public SocketState State { get; set; }
    }

    public class TcpClientReceviceEventArgs : EventArgs
    {
        public TcpClientReceviceEventArgs(byte[] data)
        {
            Data = data;
        }

        /// <summary>
        /// 接收到的原始数据
        /// </summary>
        public byte[] Data { get; set; }
    }

    public class TcpClientErrorEventArgs : EventArgs
    {
        public TcpClientErrorEventArgs(string errorMsg)
        {
            ErrorMsg = errorMsg;
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string ErrorMsg { get; set; }
    }

    public class TcpServerReceviceaEventArgs : EventArgs
    {
        public TcpServerReceviceaEventArgs(IClient iClient, byte[] data)
        {
            IClient = iClient;
            Data = data;
        }

        /// <summary>
        /// 客户端
        /// </summary>
        public IClient IClient { get; set; }

        /// <summary>
        /// 接收到的原始数据
        /// </summary>
        public byte[] Data { get; set; }
    }

    public class TcpServerClientEventArgs : EventArgs
    {
        public TcpServerClientEventArgs(IClient iClient)
        {
            IClient = iClient;
        }

        /// <summary>
        /// 客户端
        /// </summary>
        public IClient IClient { get; set; }
    }

    public class TcpServerStateEventArgs : EventArgs
    {
        public TcpServerStateEventArgs(IClient iClient, string msg, SocketState state)
        {
            IClient = iClient;
            Msg = msg;
            State = state;
        }

        /// <summary>
        /// 客户端
        /// </summary>
        public IClient IClient { get; set; }

        /// <summary>
        /// 状态消息
        /// </summary>
        public string Msg { get; set; }

        /// <summary>
        /// 状态类型
        /// </summary>
        public SocketState State { get; set; }
    }

    public class TcpServerLogEventArgs : EventArgs
    {
        public TcpServerLogEventArgs(IClient iClient, LogType logType, string logMsg)
        {
            IClient = iClient;
            LogType = logType;
            LogMsg = logMsg;
        }

        /// <summary>
        /// 客户端
        /// </summary>
        public IClient IClient { get; set; }

        /// <summary>
        /// 日志类型
        /// </summary>
        public LogType LogType { get; set; }

        /// <summary>
        /// 日志信息
        /// </summary>
        public string LogMsg { get; set; }
    }

    public class TcpServerErrorEventArgs : EventArgs
    {
        public TcpServerErrorEventArgs(string errorMsg)
        {
            ErrorMsg = errorMsg;
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string ErrorMsg { get; set; }
    }

    public class TcpServerSendReturnEventArgs : EventArgs
    {
        public TcpServerSendReturnEventArgs(IClient iClient, int byteLen)
        {
            IClient = iClient;
            ByteLen = byteLen;
        }

        /// <summary>
        /// 客户端
        /// </summary>
        public IClient IClient { get; set; }

        /// <summary>
        /// 成功发送的数据长度
        /// </summary>
        public int ByteLen { get; set; }
    }

    public class TcpServerReturnClientCountEventArgs : EventArgs
    {
        public TcpServerReturnClientCountEventArgs(int clientCount)
        {
            ClientCount = clientCount;
        }

        /// <summary>
        /// 客户端数量
        /// </summary>
        public int ClientCount { get; set; }
    }

    public class UdpReceiveDataEventArgs : EventArgs
    {
        private byte[] _buffer;
        private IPEndPoint _remoteIPendpoint;

        public UdpReceiveDataEventArgs()
        {
        }

        public UdpReceiveDataEventArgs(byte[] buffer, IPEndPoint remoteIPendpoint)
            : base()
        {
            _buffer = buffer;
            _remoteIPendpoint = remoteIPendpoint;
        }

        public byte[] Buffer
        {
            get { return _buffer; }
            set { _buffer = value; }
        }

        public IPEndPoint RemoteIPendpoint
        {
            get { return _remoteIPendpoint; }
            set { _remoteIPendpoint = value; }
        }
    }

    /// <summary>
    /// Socket状态枚举
    /// </summary>
    public enum SocketState
    {
        /// <summary>
        /// 正在连接服务端
        /// </summary>
        Connecting = 0,

        /// <summary>
        /// 已连接服务端
        /// </summary>
        Connected = 1,

        /// <summary>
        /// 重新连接服务端
        /// </summary>
        Reconnection = 2,

        /// <summary>
        /// 断开服务端连接
        /// </summary>
        Disconnect = 3,

        /// <summary>
        /// 正在监听
        /// </summary>
        StartListening = 4,

        /// <summary>
        /// 启动监听异常
        /// </summary>
        StartListeningError = 5,

        /// <summary>
        /// 停止监听
        /// </summary>
        StopListening = 6,

        /// <summary>
        /// 客户端上线
        /// </summary>
        ClientOnline = 7,

        /// <summary>
        /// 客户端下线
        /// </summary>
        ClientOnOff = 8
    }

    /// <summary>
    /// 日志类型
    /// </summary>
    public enum LogType
    {
        /// <summary>
        /// 系统
        /// </summary>
        System,

        /// <summary>
        /// 服务端
        /// </summary>
        Server,

        /// <summary>
        /// 客户端
        /// </summary>
        Client,

        /// <summary>
        /// 发送数据
        /// </summary>
        SendData,

        /// <summary>
        /// 接收数据
        /// </summary>
        ReceviedData,

        /// <summary>
        /// 发送数据返回结果
        /// </summary>
        SendDataResult
    }
}